using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using BEPUphysics.Entities;
using MagicArenaXNA.World;
using BEPUphysics.Entities.Prefabs;
using BEPUphysics.EntityStateManagement;
using BEPUphysics.CollisionShapes;
using BEPUphysics.DataStructures;
using MagicArenaXNA.Games;
using BEPUphysicsDrawer.Models;
using BEPUphysicsDemos;
using MagicArenaXNA.Assets;
using MagicArenaFramework.GameObject.Components;
using MagicArenaFramework.GameObject.Components.ConcreteTypes;
using MagicArenaXNA.ControllerInput.Bepu;
using BEPUphysics;
using MagicArenaFramework.Camera;
using MagicArenaFramework.Bepu;
using BEPUphysics.CollisionRuleManagement;
using MagicArenaXNA.GameObject.Spells;
using MagicArenaFramework.GameObject.Attributes;
using MagicArenaFramework.GameObject.Attributes.Concrete;

namespace MagicArenaXNA.GameObject
{

    public class PlayerLocalComp : GoComposite
    {
        public float Height = 2, Width=0.5f, SupportHeight=0, Mass=75 ;
        public Entity Entity { get; private set; }
        public UInt64 PlayerId { get; private set; }
        public Targetter Targetter { get; private set; }

        private SimpleCharacterController Controller;

        public PlayerLocalComp(BepuGame game, BepuWorld world, Vector3 position)
        {
            AddAtttributes();
            AddController(position);
            AddEntity(world.Space);
            AddRenderer(game.ModelDrawer);
            AddTargetter();
            AddSpellBag(game, world, Targetter);
            SetCamera(game.Camera);

            // TODO Update with getting playerId from server
            Random ran = new Random();
            this.PlayerId = (UInt64)(ran.NextDouble()*UInt64.MaxValue);
        }

        #region Adding components to player
        void AddSpellBag(BepuGame game, BepuWorld world, Targetter target)
        {
            SpellBag bag = new SpellBag(game, world, null, target);
            this.AddChild(bag);
        }

        void AddTargetter()
        {
            Targetter = new Targetter(Entity, 25);
            this.AddChild(Targetter);
        }

        void AddController(Vector3 position)
        {
            // Create Character controller and add it as a child
            Controller = new SimpleCharacterController(position, 2, .8f, 1f, 20);
            ControllerComponent contComp = new ControllerComponent(Controller);
            this.AddChild(contComp);
        }
        void AddEntity(Space space)
        {
            // Set the Bepu entity and add the controller to the physics engine
            Entity = Controller.Body;
            // Add self as component for entity
            (Entity.Tag as CustomTag).Component = this;
            space.Add(Controller);
        }
        void AddRenderer(ModelDrawer drawer)
        {
            // Create model and renderer
            Model Model = TestAssetHolder.Instance.Crono;
            EntityModelRender render = new EntityModelRender(Entity, Model, drawer);
            this.AddChild(render);
        }
        void SetCamera(ICamera camera)
        {
            // Set camera
            camera.SetChasedEntity(Controller.Body);
            camera.Mode = MagicArenaFramework.Camera.CameraMode.Chase;
        }
        void AddAtttributes()
        {
            ScalarAttributeHolder att = new ScalarAttributeHolder();
            att.AddChild(new MaxHealthAttribute(1000));
            att.AddChild(new CurHealthAttribute(1000, 500));
            att.AddChild(new RegenHealthAttribute(15));
            att.AddChild(new MaxManaAttribute(500));
            att.AddChild(new CurManaAttribute(500,250));
            att.AddChild(new RegenManaAttribute(50));
            AddChild(att);
        }
        #endregion

        // Test

    }
}
